/*
 * log.c
 *
 *  Created on: Jun 20, 2009
 *      Author: jlapointe
 */
#include "log.h"
#include <stdio.h>
#include <string.h>
#include "thread_extensions.h"
#include <unistd.h>

// TODO: make logging threaded.

// Function prototypes
void * fwriteLogThread(void * args);

// file mutex
pthread_mutex_t sharedMutex;
pthread_mutexattr_t sharedMutexAttr;

// thread variables
pthread_t writeLogThread;
pthread_attr_t threadAttr; // thread attributes

// threaded write log argument structure
typedef struct writeLogArgs
{
   char * source;
   request_t * req_t;
} writeLogArgs_t;

/*
 * This function initializes the mutex and thread attribute variables and MUST
 * be called before calling any threaded function.
 */
void logInitMutex()
{
   // Init mutex variables
   PTHREAD_MUTEXATTR_INIT(&sharedMutexAttr);
   pthread_mutex_init(&sharedMutex, &sharedMutexAttr);

   // Init thread variables
   PTHREAD_ATTR_INIT(&threadAttr);
   pthread_attr_setscope(&threadAttr, PTHREAD_SCOPE_SYSTEM);
   pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
}

/*
 * Creates a new thread that is used to write to a log and quickly return back
 * to the caller.
 */
void threadWriteLog(char * source, request_t * req_t)
{
   // setup the write log argument structure to pass to the new thread.
   writeLogArgs_t args;
   args.source = source;
   args.req_t = req_t;

   // create and start the write log worker thread.
   PTHREAD_CREATE(&writeLogThread, &threadAttr, fwriteLogThread, &args);

}

void * fwriteLogThread(void * args)
{
   writeLogArgs_t * logArgs = (writeLogArgs_t *)args;
   writeLog(logArgs->source, logArgs->req_t);
   return NULL;
}

void writeLog(char * source, request_t * req_t)
{
   if (source != NULL && req_t != NULL)
   {
      pthread_mutex_lock(&sharedMutex);

      FILE *fp;
      fp = (FILE *)fopen(LOG_LOCATION, "a");

      if (fp != NULL)
      {
         fprintf(fp, "%s - %u - %u - %u - \"%s\"\n", source, req_t->isValid,
               req_t->isNullTerm, req_t->req_length, req_t->req);
         fclose(fp);
      }

      pthread_mutex_unlock(&sharedMutex);
   }
}

void writeError(char * source, char * msg)
{
   if (source != NULL && msg != NULL)
   {
      pthread_mutex_lock(&sharedMutex);

      FILE *fp;
      fp = (FILE *)fopen(ERROR_LOG_LOCATION, "w+");

      if (fp != NULL)
      {
         fprintf(fp, "%s - \"%s\"\n", source, msg);
         fclose(fp);
      }

      pthread_mutex_unlock(&sharedMutex);
   }
}

void EraseLog()
{
   pthread_mutex_lock(&sharedMutex);
   if (access(LOG_LOCATION, F_OK) == 0)
   {
      unlink(LOG_LOCATION);
   }
+   pthread_mutex_unlock(&sharedMutex);
}

void EraseErrorLog()
{
   pthread_mutex_lock(&sharedMutex);
   if (access(ERROR_LOG_LOCATION, F_OK) == 0)
   {
      unlink(ERROR_LOG_LOCATION);
   }
   pthread_mutex_unlock(&sharedMutex);
}
